package com.mustafaiev.tair.cts.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.stereotype.Service;

import com.mustafaiev.tair.constant.Attributes;
import com.mustafaiev.tair.cts.constant.Constants;
import com.mustafaiev.tair.cts.dto.PayerDTO;
import com.mustafaiev.tair.cts.exeption.DataNotRetrievedException;
import com.mustafaiev.tair.cts.exeption.DataNotStoredException;
import com.mustafaiev.tair.cts.facade.IPayerFacade;
import com.mustafaiev.tair.cts.factory.CostTrackingSystemFacadeFactory;

@Service
public class PayerService {

	private static final Logger LOGGER = Logger.getLogger(PayerService.class);

	@Autowired
	private CostTrackingSystemFacadeFactory costTrackingSystemFacadeFactory;

	@Autowired
	private EmailSendService emailSendService;

	public List<PayerDTO> getPayers() throws DataNotRetrievedException {
		final List<PayerDTO> payers = getPayerFacade().retrievePayers();
		return payers;
	}

	public List<PayerDTO> getPayersForGroup(final Long id)
			throws DataNotRetrievedException {
		final List<PayerDTO> payers = getPayerFacade().retrievePayersForGroup(
				id);
		return payers;
	}

	public void savePayer(final PayerDTO payer) {
		try {
			getPayerFacade().savePayer(payer);
		} catch (final DataNotStoredException e) {
			LOGGER.error(e.getLocalizedMessage(), e);
		}
	}

	public void updatePayer(final PayerDTO payer) {
		try {
			getPayerFacade().updatePayer(payer);
		} catch (final DataNotStoredException e) {
			LOGGER.error(e.getLocalizedMessage(), e);
		}
	}

	public PayerDTO getPayer(final Long id) throws DataNotRetrievedException {
		return getPayerFacade().retrievePayer(id);
	}

	public PayerDTO findPayer(final String param)
			throws DataNotRetrievedException {
		return getPayerFacade().findPayer(param);
	}

	public PayerDTO retrieveByEmail(final String email)
			throws DataNotRetrievedException {
		return getPayerFacade().findPayer(email);
	}

	public PayerDTO retrieveActiveByEmail(final String email)
			throws DataNotRetrievedException {
		return getPayerFacade().retrieveActiveByEmail(email);
	}

	public boolean checkPassword(final String rawPassword,
			final String encodedPassword) {
		final StandardPasswordEncoder encoder = new StandardPasswordEncoder();
		return encoder.matches(rawPassword, encodedPassword);
	}

	public void registerPayer(final PayerDTO payer) {
		try {
			LOGGER.info("Payer registration process start");
			getPayerFacade().savePayer(payer);
			sendMail(payer);
			LOGGER.info("Payer registration process end");
		} catch (final DataNotStoredException e) {
			LOGGER.error(e.getLocalizedMessage(), e);
		}
	}

	public boolean isPayerExists(final String email)
			throws DataNotRetrievedException {
		final PayerDTO dto = findPayer(email);
		return dto != null;
	}

	private IPayerFacade getPayerFacade() {
		final IPayerFacade facade = this.costTrackingSystemFacadeFactory
				.getFacade(IPayerFacade.class);
		return facade;
	}

	private void sendMail(final PayerDTO dto) {
		LOGGER.info("Prepare email sending");
		final SimpleMailMessage msg = new SimpleMailMessage();
		msg.setTo(dto.getEmail());
		msg.setFrom(Constants.EMAIL_FROM);
		msg.setSubject(Constants.EMAIL_REGISTRATION_SUBJECT);
		final Map<Object, Object> templateVariables = new HashMap<Object, Object>();
		templateVariables.put(Attributes.PAYER, dto);
		templateVariables.put(Constants.EMAIL_TEMPLATE_FILE,
				"/registration_email_template.vm");
		this.emailSendService.send(msg, templateVariables);
	}
}
